package com.qmmessage.sdk.common;

import com.qmmessage.sdk.common.exception.QmMessageSdkException;
import com.qmmessage.sdk.common.http.Endpoint;
import com.qmmessage.sdk.common.profile.ClientProfile;
import com.qmmessage.sdk.common.util.ClientEnvUtil;
import com.qmmessage.sdk.common.util.QmSignatureUtil;
import com.qmmessage.sdk.constants.QmRequestHeader;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author qm
 */
public abstract class AbstractModel {
    /**
     * Channel Area
     */
    public enum ChannelArea {
        // China
        China,
        // Other regions except China
        Overseas
    }
    protected void initProfile(ClientProfile profile) {
        if (profile.getEndpoint() == null || profile.getEndpoint().trim().isEmpty()) {
            profile.setEndpoint(Endpoint.REST_ENDPOINT);
        }
    }

    /**
     * init header params
     * @param profile env profile
     * @param json request body json data
     */
    protected Map<String, String> initHeaders(ClientProfile profile, String json) throws QmMessageSdkException {
        // signature
        long timestamp = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString();
        Map<String, String> headers = new HashMap<>(16);
        headers.put(QmRequestHeader.Language.getCode(), profile.getLanguage().name());
        headers.put(QmRequestHeader.Version.getCode(), ClientEnvUtil.getClientVersion());
        headers.put(QmRequestHeader.Timestamp.getCode(), String.valueOf(timestamp));
        headers.put(QmRequestHeader.Uuid.getCode(), uuid);
        headers.put(QmRequestHeader.AccessKey.getCode(), profile.getAccessKey());
        String signature = QmSignatureUtil.generateSignature(timestamp, uuid, Collections.emptyMap(), json, profile.getAccessSecret());
        headers.put(QmRequestHeader.Signature.getCode(), signature);
        return headers;
    }

    /**
     * request abstract method
     * @param profile request profile
     * @param typeOfT result type
     * @return http request
     * @param <T> result type
     * @throws QmMessageSdkException qm exception
     */
    protected abstract <T extends AbstractResult> T internalRequest(ClientProfile profile, Class<T> typeOfT) throws QmMessageSdkException;
}
